#ifndef GRAPHICVIEW_H
#define GRAPHICVIEW_H

#include "gui/guievent.h"
#include "gui/graphicpainter.h"
#include "gui/elementpainter.h"
#include "gui/helperpainter.h"
#include "gui/gridhelper.h"
#include "model/model.h"
#include "app/root.h"

namespace gui
{
    /**
    *   View Interface
    *       on viewimpl event -> app actions
    *       app -> view impl
    */

    class GraphicView
    {
        GraphicPainter* painter;
        ElementPainter* elementpainter;
        HelperPainter* helperpainter;

        app::Root* document;

        GridHelper grid;

        public:
            virtual ~GraphicView();

            GraphicPainter* getGraphicPainter() {return painter;}
            void setDocumentRoot(app::Root* documentRoot);
            app::Root* getDocumentRoot() {return this->document;}
            model::Model* getModel();

            /** This virtual method must be overwritten to return
              the width of the widget the graphic is shown in */
            virtual int getWidth() = 0;
            /** This virtual method must be overwritten to return
              the height of the widget the graphic is shown in */
            virtual int getHeight() = 0;

            /** This virtual method must be overwritten to redraw
              the widget. */
            virtual void redraw() = 0;



            void setFactor(double f)
            {
                setFactorX(f);
                setFactorY(f);
            }
            void setFactorX(double f);
            void setFactorY(double f);

            Vector getFactor()
            {
                return factor;
            }

            /**
             * Sets the offset of the graphic.
             */
            void setOffset(int ox, int oy)
            {
                setOffsetX(ox);
                setOffsetY(oy);
            }
            void setOffsetX(int ox)
            {
                offsetX = ox;
            }
            void setOffsetY(int oy)
            {
                offsetY = oy;
            }
            int getOffsetX()
            {
                return offsetX;
            }
            int getOffsetY()
            {
                return offsetY;
            }
//            void centerOffsetX();
//            void centerOffsetY();


            Vector toGui(Vector v);
            double toGuiX(double x, bool* visible=NULL);
            double toGuiY(double y);
            double toGuiDX(double d);
            double toGuiDY(double d);

            Vector toGraph(Vector v);
            Vector toGraph(int x, int y);
            double toGraphX(int x);
            double toGraphY(int y);
            double toGraphDX(int d);
            double toGraphDY(int d);

        protected:
            GraphicView();

            void setPainter(GraphicPainter* painter);

            void paintAll();
            void paintModel();
            void paintHelpers();

            void rebuildView();

            // event handlers
            void onUpdateDocumentRoot();
			void onPaintEvent();
            void onResizeEvent(const SizeEvent& sizeevent);
            void onMouseEvent(const MouseEvent& mouseevent);

        private:
            Vector factor;
            int offsetX;
            int offsetY;


    };

}
#endif // GRAPHICVIEW_H
